#pragma once
#include <vector>
#include <string>
#include <memory>
#include <random>
#include "rtp.h"
#include "media.h"
#ifdef _WIN32
#include <WinSock2.h>
#endif // _WIN32


namespace jlh
{
	class RtspConnection;
	class RTPConnection
	{
	public:
		RTPConnection(std::weak_ptr<RtspConnection> rtsp_connection);
		virtual ~RTPConnection();

		void SetClockRate(MediaChannelId channel_id, uint32_t clock_rate)
		{
			media_channel_info_[channel_id].clock_rate = clock_rate;
		}

		void SetPayloadType(MediaChannelId channel_id, uint32_t payload)
		{
			media_channel_info_[channel_id].rtp_header.payload = payload;
		}

		bool SetupRtpOverTcp(MediaChannelId channel_id, uint16_t rtp_channel, uint16_t rtcp_channel);
		bool SetupRtpOverUdp(MediaChannelId channel_id, uint16_t rtp_port, uint16_t rtcp_port);
		bool SetupRtpOverMulticast(MediaChannelId channel_id, std::string ip, uint16_t port);

		uint32_t GetRtpSessionId() const
		{
			return (uint32_t)((size_t)(this));
		}

		uint16_t GetRtpPort(MediaChannelId channel_id) const
		{
			return local_rtp_port_[channel_id];
		}

		uint16_t GetRtcpPort(MediaChannelId channel_id) const
		{
			return local_rtcp_port_[channel_id];
		}

		uint32_t GetRtcpFd(MediaChannelId channel_id)
		{
			return rtcpfd_[channel_id];
		}

		bool IsMulticast() const
		{
			return is_multicast_;
		}

		bool IsSetup(MediaChannelId channel_id) const
		{
			return media_channel_info_[channel_id].is_setup;
		}

		bool IsClosed() const
		{
			return is_closed_;
		}

		bool HasKeyFrame() const
		{
			return has_key_frame_;
		}

		int GetId() const;

		void Record();

		int SendRtpPacket(MediaChannelId channel_id, RtpPacket pkt);

		void SetFrameType(uint8_t frame_type);
		void SetRtpHeader(MediaChannelId channel_id, RtpPacket pkt);

		int SendRtpOverTcp(MediaChannelId channel_id, RtpPacket pkt);
		int SendRtpOverUdp(MediaChannelId channel_id, RtpPacket pkt);

		void Teardown();

		void Play();
	private:
		std::weak_ptr<RtspConnection> rtsp_connection_;

		TransportMode transport_mode_ = TransportMode::RTP_OVER_TCP;
		bool is_multicast_ = false;

		bool is_closed_ = false;
		bool has_key_frame_ = false;

		uint8_t frame_type_ = 0;
		uint16_t local_rtp_port_[MAX_MEDIA_CHANNEL];
		uint16_t local_rtcp_port_[MAX_MEDIA_CHANNEL];
		uint32_t rtpfd_[MAX_MEDIA_CHANNEL];
		uint32_t rtcpfd_[MAX_MEDIA_CHANNEL];

		struct sockaddr_in peer_addr_;
		struct sockaddr_in peer_rtp_addr[MAX_MEDIA_CHANNEL];
		struct sockaddr_in peer_rtcp_addr_[MAX_MEDIA_CHANNEL];
		MediaChannelInfo media_channel_info_[MAX_MEDIA_CHANNEL];

	};
}


